﻿using System;
using System.Drawing;
using System.Text;
using RRRSRoguelike.Enums;
using RRRSRoguelike.Managers;

namespace RRRSRoguelike.Helpers.Visualizer
{
	/// <summary>
	/// Contains the code for displaying text within the game panels.
	/// </summary>
	public class Panel
	{

		#region variables
		private Point firstCharacter;
		private int lengthInCharacters;
		private int heightInCharacters;

		private string currentString;
		private ConsoleColor currentColor;
		private TextAlignment currentTextAlignment;
		private int currentLine;

		string borderCharacter;
		ConsoleColor borderColor;

		int height;
		int width;

		Visualizer dungeonVisualizer = GameManager.Instance.DungeonVisualizer;

		/// <summary>
		/// Checks if panel is clear
		/// </summary>
		public bool IsClear
		{
			get { return string.IsNullOrEmpty(currentString); }
		}

		/// <summary>
		/// Top left corner.
		/// </summary>
		Point position;
		#endregion

		#region constructor

		/// <summary>
		/// Creates an instance of panel
		/// </summary>
		/// <param name="position"></param>
		/// <param name="width"></param>
		/// <param name="height"></param>
		/// <param name="borderCharacter"></param>
		/// <param name="borderColor"></param>
		public Panel(Point position, int width, int height,
			string borderCharacter = "+", ConsoleColor borderColor = ConsoleColor.White)
		{
			currentString = "";
			currentColor = ConsoleColor.White;
			this.position = position;
			firstCharacter = new Point(position.X + 2, position.Y + 2);
			lengthInCharacters = width - 4;
			heightInCharacters = height - 4;
			this.height = height;
			this.width = width;
			this.borderCharacter = borderCharacter;
			this.borderColor = borderColor;
		}
		#endregion

		#region methods

		/// <summary>
		/// clears a single line in the panel
		/// </summary>
		/// <param name="line"></param>
		public void ClearLine(int line)
		{
			Write(PrepareLine().ToString(), line);
		}

		StringBuilder PrepareLine()
		{
			StringBuilder horizontaLine = new StringBuilder();

			//prepareline
			for (int i = 0; i < lengthInCharacters; i++)
				horizontaLine.Append(" ");

			return horizontaLine;
		}

		/// <summary>
		/// clears the panel
		/// </summary>
		/// <param name="nullCurrentString"></param>
		public void Clear(bool nullCurrentString = true)
		{
			if (nullCurrentString)
				currentString = null;

			StringBuilder sb = new StringBuilder();
			string line = PrepareLine().ToString();

			for (int j = 2; j < height - 2; j++)
				sb.AppendLine(line);

			Visualizer.WriteMultiLine(
				sb.ToString(), firstCharacter, ConsoleColor.White);
		}
		
		/// <summary>
		/// Write string to the panel using the visualizer.
		/// </summary>
		/// <param name="text"></param>
		/// <param name="line"></param>
		/// <param name="color"></param>
		/// <param name="textAlignment"></param>
		/// <param name="options"></param>
		public void Write(string text, int line = 0, ConsoleColor color = ConsoleColor.White,
						  TextAlignment textAlignment = TextAlignment.Single,
						  StringSplitOptions options = StringSplitOptions.None)
		{
			Point start = firstCharacter;
			if (line < heightInCharacters)
				start.Y += line;

			//only draw if changed
			if (currentColor != color || currentString != text || 
			    currentTextAlignment != textAlignment || currentLine != line)
			{
				currentColor = color; currentString = text; currentTextAlignment = textAlignment; currentLine = line;

				switch (textAlignment)
				{
					case TextAlignment.Single:
						if (text.Length > lengthInCharacters)
							text = text.Remove(lengthInCharacters);
						Visualizer.WriteLine(text, start, color);
						break;
					case TextAlignment.Center:
						text = Visualizer.CentralizeText(text, lengthInCharacters);
						Visualizer.WriteLine(text, start, color);
						break;
					case TextAlignment.Multi:
						Visualizer.WriteMultiLine(
					Visualizer.BuildString(text, lengthInCharacters).ToString(), start, color, options);
						break;
				}
			}
		}

		/// <summary>
		/// Draws the panel
		/// </summary>
		public void Draw()
		{
			StringBuilder horizontaLine = new StringBuilder();

			//prepareline
			for (int i = 0; i < width; i++)
				horizontaLine.Append(borderCharacter);
			//Top
			Visualizer.WriteLine(horizontaLine.ToString(), position, borderColor);

			//Bottom
			Visualizer.WriteLine(horizontaLine.ToString(),
				new Point(position.X, position.Y + height - 1), borderColor);

			for (int i = 0; i < height; i++)
			{
				//Left
				Visualizer.WriteLine(borderCharacter,
						new Point(position.X, position.Y + i), borderColor);
				//Right
				Visualizer.WriteLine(borderCharacter,
				new Point(position.X + width - 1, position.Y + i), borderColor);
			}
		}
		#endregion

	}
}
